<template>
  <tm-scrolly
    v-model="refreshLoading"
    :height="listHeight"
    v-model:bottomValue="bottomLoading"
    @refresh="refreshList"
    @bottom="loadMore"
  >
    <slot :list="list"></slot>
    <view class="no-data" v-if="!list.length && !initLoading">
      <slot name="no-data"> 暂无数据</slot>
    </view>
    <view class="no-data" v-else-if="query.pageNum >= pages && !initLoading">
      <slot name="no-data"> 暂无更多数据</slot>
    </view>
    <tm-icon
      v-if="initLoading"
      spin
      color="#999999"
      class="!tw-mt-10"
      name="tmicon-shuaxin"
    ></tm-icon>
  </tm-scrolly>
</template>

<script setup lang="ts">
const props = withDefaults(
  defineProps<{
    //指定分页单位,不支持动态改变
    pageSize?: number;
    //用于处理列表数据,比如添加key
    formatList?: (list: any[]) => any[];
    //是否自动加载列表,关闭后需要手动调用refreshList方法
    autoLoad?: boolean;
    height?: number;
    //自动高度,传入数字时使用屏幕高度减去该值,传入true时使用屏幕高度
    autoFullHeight?: boolean | number;
  }>(),
  {
    pageSize: 10,
    autoLoad: true,
    height: 600,
  },
);

const listHeight = computed(() => {
  //获取显示区域高度
  let height = uni.$tm.u.torpx(uni.getWindowInfo().windowHeight);

  //H5下在tabbar页面+tabbar高度
  //#ifdef H5
  height = height + uni.getSystemInfoSync().windowBottom;
  //#endif

  if (props.autoFullHeight === true) {
    return height;
  } else if (typeof props.autoFullHeight === "number") {
    return height - props.autoFullHeight;
  } else {
    return props.height;
  }
});

const emits = defineEmits<{
  (
    e: "load-data",
    pageNum: number,
    pageSize: number,
    cb: (data: { list: any[]; pages: number; total: number }) => void,
  ): void;
}>();

import { computed, onMounted, ref } from "vue";

const refreshLoading = ref(false);
const bottomLoading = ref(false);
const initLoading = ref(true);
const query = ref({
  pageNum: 1,
  pageSize: props.pageSize,
});

const list = ref<any[]>([]);

//下拉刷新,重置页码清除数据
function refreshList() {
  query.value.pageNum = 1;
  emits(
    "load-data",
    query.value.pageNum,
    query.value.pageSize,
    (data: { list?: any[]; pages?: number; total?: number }) => {
      list.value = props.formatList
        ? props.formatList(data.list || [])
        : data.list || [];
      pages.value = data.pages || 0;
      refreshLoading.value = false;
      initLoading.value = false;
    },
  );
}

const pages = ref(0);

//上拉加载
function loadMore() {
  if (bottomLoading.value || query.value.pageNum >= pages.value) {
    return;
  }
  bottomLoading.value = true;
  query.value.pageNum++;
  emits(
    "load-data",
    query.value.pageNum,
    query.value.pageSize,
    (data: { list?: any[]; pages?: number; total?: number }) => {
      list.value = list.value.concat(
        props.formatList ? props.formatList(data.list || []) : data.list || [],
      );
      pages.value = data.pages || 0;
      bottomLoading.value = false;
    },
  );
}

onMounted(() => {
  if (props.autoLoad) {
    refreshList();
  }
});

defineExpose({
  list,
  refreshLoading,
  bottomLoading,
  query,
  //导出加载方法用于手动初始化加载
  refreshList,
});
</script>

<style scoped lang="scss">
.no-data {
  font-size: 24rpx;
  color: #999999;
  text-align: center;
  padding: 40px 0;
}
</style>
